
package com.hlkj.pay.app.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelComplaintOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRiskOrderContext;
import com.hlkj.pay.app.merchant.impl.CommonChannelCallHandler;
import com.hlkj.pay.app.order.IComplaintOrderAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.dto.order.RiskOrderQueryDto;
import com.hlkj.pay.dto.order.notify.OrderComplaintNotifyDto;
import com.hlkj.pay.dto.order.notify.OrderRiskNotifyDto;
import com.hlkj.pay.gateway.order.IChannelComplaintGateway;
import com.hlkj.pay.gateway.order.IChannelRiskGateway;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintHistoryDO;
import com.hlkj.pay.infrastructure.model.order.OrderRiskDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.merchant.IMerchantAccessAuthService;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.service.order.IOrderComplaintChannelService;
import com.hlkj.pay.service.order.IOrderComplaintService;
import com.hlkj.pay.service.order.IOrderRiskService;
import com.hlkj.pay.task.CommonTasks;

import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/12/29 16:18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ComplaintOrderAppServiceImpl implements IComplaintOrderAppService {

    private final IChannelComplaintGateway complaintGateway;

    private final IMerchantAccessService merchantAccessService;

    private final IMerchantAccessAuthService merchantAccessAuthService;

    private final IChannelRiskGateway riskGateway;

    private final CommonChannelCallHandler commonChannelCallHandler;

    private final IOrderComplaintChannelService orderComplaintChannelService;

    private final IOrderComplaintService orderComplaintService;

    private final IOrderRiskService orderRiskService;

    private final CommonTasks commonTasks;


    @Override
    public String complaintCallBack(Long id, HttpServletRequest request) {
        log.info("complaintCallBack start");
        // 获取投诉通道配置
        OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelService.queryDetail(id);
        if(orderComplaintChannelDO == null){
            log.error("投诉通知回调回调失败，渠道配置不存在, ID:{}",id);
            return "FAIL";
        }
        String channelCode = orderComplaintChannelDO.getChannelCode();
        if(StrUtil.isEmpty(orderComplaintChannelDO.getBaseConfig())){
            return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
        }

        ProviderChannelConfigDO providerChannelConfigDO = new ProviderChannelConfigDO();
        providerChannelConfigDO.setChannelCode(channelCode);
        providerChannelConfigDO.setParamsConfig(orderComplaintChannelDO.getBaseConfig());
        log.info("complaintCallBack query");
        // 获取详情
        ChannelComplaintOrderContext channelComplaintOrderContext = new ChannelComplaintOrderContext();
        channelComplaintOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
        channelComplaintOrderContext.setProcessStatus(true);
        CommonResult<OrderComplaintNotifyDto> commonResult = complaintGateway.complaintStatusParse(request, channelComplaintOrderContext);
        log.info("complaintCallBack complaintStatusParse");
        if(!channelComplaintOrderContext.isProcessStatus()){
            return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.error(CommonResultCode.DATA_NOT_EFFECT));
        }
        // 异步同步数据
        OrderComplaintDO updateOrderComplaintDO = commonResult.getData().getOrderComplaint();
        updateOrderComplaintDO.setChannelId(id);
        // 查询数据库
        OrderComplaintDO complaintDO = orderComplaintService.queryDetailByComplaintId(updateOrderComplaintDO.getComplaintId());
        // 协商历史数据
        OrderComplaintHistoryDO orderComplaintHistoryDO = commonResult.getData().getOrderComplaintHistoryDO();
        // 数据库已有记录
        if(complaintDO != null){
            updateOrderComplaintDO.setId(complaintDO.getId());
            commonTasks.complaintSyncData(updateOrderComplaintDO,orderComplaintHistoryDO,false);
            log.info("complaintCallBack update:{}", JsonUtils.toJsonString(updateOrderComplaintDO));
        }else{
            commonTasks.complaintSyncData(updateOrderComplaintDO,orderComplaintHistoryDO,true);
            log.info("complaintCallBack add:{}", JsonUtils.toJsonString(updateOrderComplaintDO));
        }
        return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.success());
    }

    @Override
    public String riskCallBack(Long id, HttpServletRequest request) {
        // 获取风险通道配置
        OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelService.queryDetail(id);
        if(orderComplaintChannelDO == null){
            log.error("风险通知回调回调失败，渠道配置不存在, ID:{}",id);
            return "FAIL";
        }
        String channelCode = orderComplaintChannelDO.getChannelCode();
        if(StrUtil.isEmpty(orderComplaintChannelDO.getBaseConfig())){
            return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
        }

        ProviderChannelConfigDO providerChannelConfigDO = new ProviderChannelConfigDO();
        providerChannelConfigDO.setChannelCode(channelCode);
        providerChannelConfigDO.setParamsConfig(orderComplaintChannelDO.getBaseConfig());

        // 获取解析数据
        ChannelRiskOrderContext channelRiskOrderContext = new ChannelRiskOrderContext();
        channelRiskOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
        channelRiskOrderContext.setProcessStatus(true);
        CommonResult<OrderRiskNotifyDto> commonResult = riskGateway.riskStatusParse(request, channelRiskOrderContext);
        if(!channelRiskOrderContext.isProcessStatus()){
            return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.error(CommonResultCode.DATA_NOT_EFFECT));
        }

        // 回调数据
        OrderRiskDO updateOrderRiskDO = commonResult.getData().getOrderRiskDO();
        updateOrderRiskDO.setChannelId(id);
        updateOrderRiskDO.setType(orderComplaintChannelDO.getType());

        // 通过sub_mchid查询报备信息
        MerchantAccessAuthDO authDO = new MerchantAccessAuthDO();
        authDO.setSubMchId(updateOrderRiskDO.getSubMchid());
        MerchantAccessAuthDO merchantAccessAuthDO =  merchantAccessAuthService.queryMerchantAccessAuth(authDO);
        if(merchantAccessAuthDO != null){
            updateOrderRiskDO.setSn(merchantAccessAuthDO.getSn());
            updateOrderRiskDO.setAccessId(merchantAccessAuthDO.getAccessId());

            // 查询进件信息
            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(merchantAccessAuthDO.getAccessId());
            if(merchantAccessInfoDO != null){
                updateOrderRiskDO.setProviderCode(merchantAccessInfoDO.getProviderCode());
                updateOrderRiskDO.setChannelCode(merchantAccessInfoDO.getChannelCode());
            }

        }else{
            log.error("riskCallBack 未查询到报备商户号:{}", JsonUtils.toJsonString(updateOrderRiskDO));
        }

        // 查询数据库
        RiskOrderQueryDto riskOrderQueryDto = new RiskOrderQueryDto();
        riskOrderQueryDto.setRiskId(updateOrderRiskDO.getRiskId());
        OrderRiskDO orderRiskDO = orderRiskService.selectOne(riskOrderQueryDto);
        // 数据库已有记录
        if(orderRiskDO != null){
            updateOrderRiskDO.setId(orderRiskDO.getId());
            orderRiskService.updateOrderRisk(updateOrderRiskDO);
            log.info("riskCallBack update:{}", JsonUtils.toJsonString(updateOrderRiskDO));
        }else{
            orderRiskService.addOrderRisk(updateOrderRiskDO);
            log.info("riskCallBack add:{}", JsonUtils.toJsonString(updateOrderRiskDO));
        }
        return commonChannelCallHandler.processComplaintLogAndResponse(channelCode, CommonResult.success());
    }

}
